/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#include "ohos_types.h"
#include "ohos_init.h"
#include "hilog/log.h"
#include "thread_adapter.h"
#include "time_adapter.h"
#include "service.h"
#include "samgr_lite.h"
#include <cJSON.h>
#//include "utils_log.h"

#include "update_lite_manager.h"
//#include "mqtt_ota.h"

int updataStatus = 0; 
int count = 0; // 记录缓冲区中的数据数量
pthread_mutex_t mutex;
pthread_cond_t msgsignal;




static void *UpdateTaskThread(void *argv)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ----UpdateTaskThread Enter....[%d]", pthread_self());
    // 1、获取固件信息（获取过程中各种异常处理，及反馈）
    UpdateLiteInfo minfo;
    //GetFirmwareInfo(&minfo);   //与下一步之间为异步运行
    
    while (1)
    {
        HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread--------while before wait, updataStatus = %d\n", updataStatus);
        pthread_mutex_lock(&mutex); // 锁定互斥锁
        if (count <= 0) 
        {
            pthread_cond_wait(&msgsignal, &mutex);
            if(count <= 0)
            {
                continue;
            }
        }
        count--;
        switch (updataStatus)
        {
        case 0:
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread ---- case 0\n");
            preGetFirmwareInfo(&ulinfo);
            updataStatus = 1;
            break;
        case 1:
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread ---- case 1\n");
            preDownloadFirmware(&ulinfo);
            updataStatus = 2;
            break;
        case 2:
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread ---- case 2\n");
            CheckFirmwarePackage(&minfo);
            UpdateLocaldetection();
            updataStatus = 0;
            break;

        default:
            updataStatus = 0;
            break;
        }
        pthread_mutex_unlock(&mutex); // 解锁互斥锁
        HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread--------while after wait, updataStatus = %d\n", updataStatus);
    }

    // 2、固件信息验证（固件信息各种错误反馈）
    //CheckFirmwareInfo(&minfo);

    // 3、下载固件（下载过程中各种异常处理，及反馈）
    //DownloadFirmware(&minfo);

    // 4、固件包验证（固件包各种异常反馈）
    //CheckFirmwarePackage(&minfo);

    // 5、升级环境验证（升级环境各种异常反馈）
    //UpdateLocaldetection();

    // 6、启动升级（重启设备进行包烧写）
    //WriteMiscAndReboot();

    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateTaskThread ---- end\n");
    return NULL;
}

uint32_t CheckFirmwareInfo(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... CheckFirmwareInfo\n");

    return 1;
}

uint32_t CheckFirmwarePackage(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... CheckFirmwarePackage\n");

    return 0;
}

uint32_t UpdateLocaldetection()
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateLocaldetection\n");

    return 0;
}

void WriteMiscAndReboot()
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... WriteMiscAndReboot\n");
}

void GetUpdateResultInfo(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... GetUpdateResultInfo-----\n");
    // 读取包烧写处理结果信息（如没有信息则不需要处理）


}

void UpdateResultInfo()
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateResultInfo-----begain\n");
    UpdateLiteInfo minfo;
    GetUpdateResultInfo(&minfo);
    //上报包烧写处理结果信息（调用如mqtt lib上报信息接口）
    ReportUpdateResultInfo(&minfo);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateResultInfo-----end\n");
}

void GetCurrentInfo(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... GetCurrentInfo-----begain\n");
    //搜集当前ota升级所需要的版本信息及设备信息
    LocalGetCurrentInfo(info);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... GetCurrentInfo-----end\n");
}

bool firmwareParse(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... firmwareParse--------\n");
    return true;
}

void DownloadPkgCallback(struct UpdateLiteInfo *info, int success)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadPkgCallback--------\n");
    count++;
    //校验package
    //CheckFirmwarePackage(info);
    //启动升级

    //上报升级状态及结果

}

void preDownloadFirmware(struct UpdateLiteInfo *info)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preDownloadFirmware--------firmwareUrl : %s\n", firmwareUrl);
    // cJSON *message_body = cJSON_Parse((char*)info->payload);
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preDownloadFirmware--------\n");
    // cJSON *msgInfo = cJSON_GetObjectItem(message_body, "msgInfo");
    // cJSON *urljson = cJSON_GetObjectItem(msgInfo, "url");
    // const char *url = cJSON_GetStringValue(urljson);
    // int urllen = strlen(url);
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preDownloadFirmware-------urllen = %d, url : %s\n", urllen, url);
    // ulinfo.payload = NULL;

    if(firmwareParse(&ulinfo))
    {
        if(CheckFirmwareInfo(&ulinfo) == 1)
        {
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preDownloadFirmware--------to DownloadFirmware\n");
            DownloadFirmware(&ulinfo, firmwareUrl, DownloadPkgCallback);
        } else {
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preDownloadFirmware--------report CheckFirmwareInfo error\n");
        }
    }  
}

static void *recvFirmwareInfoThread(void *argv)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... recvFirmwareInfoThread--------\n");
    if(firmwareParse(&ulinfo))
    {
        if(CheckFirmwareInfo(&ulinfo) == 1)
        {
            //DownloadFirmware(&ulinfo, DownloadPkgCallback);
        } else {
            HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... recvFirmwareInfoThread--------report CheckFirmwareInfo error\n");
        }
    }
}

void DownloadInfoCallback(struct UpdateLiteInfo *info, int success)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------1\n");
    ulinfo.msgtype = info->msgtype;
    ulinfo.transType = success;
    ulinfo.msgid = info->msgid;
    ulinfo.payloadlen = info->payloadlen;
    ulinfo.payload = (uint8_t*)info->payload;

    // 添加下面代码会挂掉,逐句放开调试
    cJSON *message_body = cJSON_Parse((char*)info->payload);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------2\n");
    cJSON *msgInfo = cJSON_GetObjectItem(message_body, "msgInfo");
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------3\n");
    cJSON *urljson = cJSON_GetObjectItem(msgInfo, "url");
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------4\n");
    const char *url = cJSON_GetStringValue(urljson);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------5-----url: %s\n", url);
    //int urllen = strlen(url);   //不能使用这种方式来获取char *s的长度
    //HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------6\n");
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback-------urllen = %d, url : %s\n", urllen, url);

    //firmwareUrl[0] = '\n';
    //char *pdest = firmwareUrl;
    //while (*pdest++ = *url++) {}
    firmwareUrl = "http://10.50.80.72:5000/ota/updater.zip";
    count++;
    //pthread_cond_signal(&msgsignal);
    // if(firmwareParse(&info))
    // {
    //     if(CheckFirmwareInfo(&info) == 1)
    //     {
    //         DownloadFirmware(&info, DownloadPkgCallback);
    //     } else {
    //         HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... DownloadInfoCallback--------report CheckFirmwareInfo error\n");
    //     }
    // }
}

static void *getFirmwareInfoThread(void *argv)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread--------\n");


    



   // cJSON *message_body = cJSON_Parse((char*)(ulinfo.payload));
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread--------2-------\n");
    // cJSON *msgInfo = cJSON_GetObjectItem(message_body, "msgInfo");
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread--------3-------\n");
    // cJSON *urljson = cJSON_GetObjectItem(msgInfo, "url");
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread--------4-------\n");
    // const char *url = cJSON_GetStringValue(urljson);
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread--------5-------\n");
    // int urllen = strlen(url);
    // HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... getFirmwareInfoThread-------urllen = %d, url : %s\n", urllen, url);
    // GetFirmwareInfo(&ulinfo, url);
}

void preGetFirmwareInfo(struct UpdateLiteInfo *info)
 {
    // ThreadAttr attr = {"getFirmwareInfoThread thread", 1024, 2, 0, 0};
    // ThreadId threadId = (ThreadId)THREAD_Create(getFirmwareInfoThread, NULL, &attr);
    cJSON *message_body = cJSON_Parse((char*)info->payload);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preGetFirmwareInfo--------\n");
    cJSON *msgInfo = cJSON_GetObjectItem(message_body, "msgInfo");
    cJSON *urljson = cJSON_GetObjectItem(msgInfo, "url");
    const char *url = cJSON_GetStringValue(urljson);
    int urllen = strlen(url);
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... preGetFirmwareInfo-------urllen = %d, url : %s\n", urllen, url);
    ulinfo.payload = NULL;
    GetFirmwareInfo(&ulinfo, url, DownloadInfoCallback);
}

void UpdateLite_Callback(struct UpdateLiteInfo *info)
{
    //HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateLite_Callback\n");
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ----UpdateLite_Callback, payloadlen: %d, msgid: %d, message:\n %s\n", info->payloadlen, info->msgid, (char*)info->payload);

    // ulinfo.msgtype = info->msgtype;
    // ulinfo.transType = 1;
    // ulinfo.msgid = info->msgid;
    // ulinfo.payloadlen = info->payloadlen;
    // //需要添加申请内存并将payload拷贝一份出来，开辟线程处理时
    // // char *ptr = realloc(ulinfo.payload, ulinfo.payloadlen + 1);
    // // if(ptr == NULL) {
    // //     /* out of memory! */ 
    // //     HILOG_INFO(LOG_CORE,"not enough memory (realloc returned NULL)");
    // //     return 0;
    // // }
    // // ulinfo.payload = ptr;
    // // memcpy(ulinfo.payload, info->payload, ulinfo.payloadlen);
    // ulinfo.payload = (uint8_t*)info->payload;

    // switch (info->msgtype)
    // {
    // case MSG_STARTOTA:
    //     HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateLite_Callback--------MSG_STARTOTA\n");
    //     //preGetFirmwareInfo(&ulinfo);
    //     count++;
    //     pthread_cond_signal(&msgsignal);
    //     break;
    // case MSG_GETCURRENTINFO:
    //     HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateLite_Callback--------MSG_GETCURRENTINFO\n");
    //     //GetCurrentInfo(&ulinfo);
    //     count++;
    //     pthread_cond_signal(&msgsignal);
    //     break;
    // case MSG_FIRMWAREINFO:
    //     HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateLite_Callback--------MSG_FIRMWAREINFO\n");
    //     // ThreadAttr attr = {"recvFirmwareInfoThread thread", 1024, 2, 0, 0};
    //     // ThreadId threadId = (ThreadId)THREAD_Create(recvFirmwareInfoThread, NULL, &attr);
    //     count++;
    //     pthread_cond_signal(&msgsignal);
    //     break;
    // default:
    //     break;
    // }
}

uint32_t InitConnect(int connecttype)
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- InitConnect .... THREAD_Create\n");
    // ThreadAttr attr = {"UpdateTaskThread thread", 1024, 2, 0, 0};
    // ThreadId threadId = (ThreadId)THREAD_Create(UpdateTaskThread, NULL, &attr);

    switch (connecttype)
    {
    case UPDATELITE_MQTT:   /* constant-expression */
        HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- InitConnect .... UPDATELITE_MQTT\n");
        InitMQTTConnect(UpdateLite_Callback);  /* code */
        //UpdateResultInfo(99);  //系统启动检测是否是刚升级完成，如果刚升级完成第一次启动就需要上报升级结果
        break;

    default:
        break;
    }
    return 0;
}

uint32_t UpdateClean()
{
    HILOG_INFO(LOG_CORE, "update_lite_manager.c ---- .... UpdateClean--------\n");
    return 0;
}
